package de.servicezombie.tcmdb.rest.vo;

import java.util.Collections;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.commons.lang.StringUtils;

import de.servicezombie.lang.ListUtils;
import de.servicezombie.pub.r1.XmlNamespaces;

/**
 * <p>
 * A definition of a single testcase.
 * </p>
 * <b>Example:</b>
 * 
 * <pre>
 * testcaseDefinition {
 *   id: 815,
 *   title: "A nearly unqiue title."
 *   description: "a long multiline description",
 *   expectedResult: "a long multiline description of the 
 *   results expected by execution",
 *   author: { name: ..., email: ... }
 *   effort: { value: 15, timeUnit: (MINUTES|HOURS|DAYS) }
 *   tags: "space separated list-of-tags",
 *   severity: "BLOCKER" // enumeration
 *   knownBugs: [
 *   	softwareBug { ... }
 *      softwareBug { ... }
 *   ],
 *   steps [ // already ordered
 *     testcaseStep { index=0, ... }
 *     testcaseStep { index=1, ... }
 *     testcaseStep { index=2, ... }
 *   ],
 *   
 * }
 * </pre>
 * 
 * @author ChKa
 * @version n.a.
 * @see Severity
 */
@XmlRootElement(name = "testcaseDefinition")
@XmlAccessorType(XmlAccessType.FIELD)
public class WsTestcaseDefinition extends AbstractWsDomainObjectWithId<WsTestcaseDefinition> {

	/**
	 * @unique
	 */
	@XmlElement(name = "title", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON)
	private String title;

	@XmlElement(name = "description", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON)
	private String description;

	@XmlElement(name = "expectedResult", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON)
	private String expectedResult;

	@XmlElement(name = "owner", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON)
	private WsAuthor owner;
	
	@XmlElement(name = "effort", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON)
	private WsEffort effort;

	@XmlElement(name = "tags", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON)
	private String tags;

	@XmlElement(name = "severity", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON)
	private Severity severity;

	@XmlElementWrapper(name = "knownBugs", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON, nillable = true)
	@XmlElement(name = "softwareBug", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON, type = WsSoftwarebug.class)
	private List<WsSoftwarebug> knownBugs;

	@XmlElementWrapper(name = "steps", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON, nillable = true)
	@XmlElement(name = "step", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON, type = WsTestcaseStep.class)
	private List<WsTestcaseStep> steps;

	@XmlElementWrapper(name = "applications", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON, nillable = false)
	@XmlElement(name = "application", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON, type = WsApplication.class)
	private List<WsApplication> applications;
	
	@XmlElement(name = "status", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON)
	private ActivityStatus status;
	
	@XmlElement(name = "access", namespace = XmlNamespaces.SERVICEZOMBIE_COMMON)
	private WsAccessRecord access;
	
	public WsAccessRecord getAccess() {
		if(access == null) {
			return new WsAccessRecord();
		}
		return access;
	}
	
	public void setAccess(WsAccessRecord access) {
		this.access = access;
	}
	
	public void setStatus(ActivityStatus status) {
		this.status = status;
	}
	
	public ActivityStatus getStatus() {
		if(status == null) {
			return ActivityStatus.UNKNOWN;
		}
		return status;
	}
	
	
	public void addApplication(WsApplication application) {
		applications = ListUtils.emptyListIfNull(applications);
		this.applications.add(application);
	}
	
	public void removeApplication(WsApplication application) {
		if(applications == null) return;
		this.applications.remove(application);
	}	
	
	public List<WsApplication> getApplications() {
		applications = ListUtils.emptyListIfNull(applications);
		return Collections.unmodifiableList(applications);
	}
	
	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public WsAuthor getOwner() {
		return owner;
	}

	public void setOwner(WsAuthor author) {
		this.owner = author;
	}

	public String[] getTagsAsArray() {
		String[] tagsArray = StringUtils.split(this.tags, " ,;\t");
		return tagsArray != null ? tagsArray : new String[0];
	}

	public String getTags() {
		return tags;
	}

	public void setTags(String tags) {
		this.tags = tags;
	}

	public Severity getSeverity() {
		return severity;
	}

	public void setSeverity(Severity severity) {
		this.severity = severity;
	}

	public List<WsSoftwarebug> getKnownBugs() {
		knownBugs = ListUtils.emptyListIfNull(knownBugs);
		return knownBugs;
	}

	public void setKnownBugs(List<WsSoftwarebug> knownBugs) {
		this.knownBugs = knownBugs;
	}

	public List<WsTestcaseStep> getSteps() {
		steps = ListUtils.emptyListIfNull(steps);
		return steps;
	}

	public void setSteps(List<WsTestcaseStep> steps) {
		this.steps = steps;
	}

	public String getExpectedResult() {
		return expectedResult;
	}

	public void setExpectedResult(String expectedResult) {
		this.expectedResult = expectedResult;
	}
	
	public WsEffort getEffort() {
		if(effort == null) {
			effort = new WsEffort();
		}
		return effort;
	}

	public void setEffort(WsEffort effort) {
		this.effort = effort;
	}	

}
